﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;

using System.Runtime.InteropServices;
using System.Reflection;
using Microsoft.Win32;

namespace CLFramework.Windows.Forms
{
    public class ModalHost : Form
    {
        #region DllImport

        [DllImport("user32.dll")]
        public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);

        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern bool UnhookWindowsHookEx(int idHook);

        [DllImport("user32.dll")]
        public static extern int CallNextHookEx(int idHook, int nCode, int wParam, IntPtr lParam);

        [DllImport("kernel32.dll")]
        public static extern int GetCurrentThreadId();

        [DllImport("kernel32.dll")]
        public static extern IntPtr GetModuleHandle(string name);

        [StructLayout(LayoutKind.Sequential)]
        public class KeyBoardHookStruct
        {
            public int vkCode;
            public int scanCode;
            public int flags;
            public int time;
            public int dwExtraInfo;
        }

        #endregion

        #region Members

        private System.ComponentModel.IContainer components = null;

        public delegate int HookProc(int nCode, int wParam, IntPtr lParam);

        static int hHook = 0;

        public const int WH_KEYBOARD_LL = 13;

        HookProc KeyBoardHookProcedure;

        #endregion

        #region Properties

        ModalPopup popup;

        public ModalPopup Popup
        {
            get { return popup; }
            set { popup = value; }
        }

        #endregion

        #region Ctor.

        public ModalHost(ModalPopup popup)
        {
            InitializeComponent();
            this.popup = popup;
            //Bind();
        }

        private void Bind()
        {
            Popup.StartPosition = FormStartPosition.CenterScreen;
            Popup.TopMost = true;
            Popup.Host = this;
            Popup.ControlBox = false;
            Popup.Show(this);
        }

        #endregion

        #region Functions

        public void Hook_Start()
        {
            if (hHook == 0)
            {
                KeyBoardHookProcedure = new HookProc(KeyBoardHookProc);

                hHook = SetWindowsHookEx(WH_KEYBOARD_LL,
                          KeyBoardHookProcedure,
                        GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), 0);

                if (hHook == 0)
                {
                    Hook_Clear();
                }
            }
        }

        public void Hook_Clear()
        {
            bool retKeyboard = true;
            if (hHook != 0)
            {
                retKeyboard = UnhookWindowsHookEx(hHook);
                hHook = 0;
            }

            if (!retKeyboard)
                throw new Exception("UnhookWindowsHookEx failed.");
        }

        public static int KeyBoardHookProc(int nCode, int wParam, IntPtr lParam)
        {
            return CallNextHookEx(hHook, nCode, wParam, lParam);
        }

        #endregion

        #region Event Handlers

        void ModalHost_Load(object sender, EventArgs e)
        {
            Hook_Start();
            Bind();
        }

        void ModalHost_FormClosing(object sender, FormClosingEventArgs e)
        {
            Hook_Clear();
        }

        #endregion

        #region Designer

        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        private void InitializeComponent()
        {
            this.SuspendLayout();
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
            this.KeyPreview = true;
            this.Opacity = 0.6D;
            this.ShowInTaskbar = false;
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
            this.WindowState = System.Windows.Forms.FormWindowState.Maximized;
            this.ResumeLayout(false);

            this.Load += new EventHandler(ModalHost_Load);
            this.FormClosing += new FormClosingEventHandler(ModalHost_FormClosing);
        }

        #endregion
    }
}